package com.gitee.randomobject.config;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.http.HttpMethod;
import org.springframework.security.config.annotation.web.builders.HttpSecurity;
import org.springframework.security.oauth2.config.annotation.web.configuration.EnableResourceServer;
import org.springframework.security.oauth2.config.annotation.web.configuration.ResourceServerConfigurerAdapter;
import org.springframework.security.oauth2.config.annotation.web.configurers.ResourceServerSecurityConfigurer;
import org.springframework.security.oauth2.provider.token.TokenStore;
import org.springframework.security.oauth2.provider.token.store.JdbcTokenStore;

import javax.sql.DataSource;

@Configuration
@EnableResourceServer
public class OauthResourcesConfig extends ResourceServerConfigurerAdapter {

    @Autowired
    private DataSource dataSource;

    /**
     * 指定token的持久化策略
     * @return JdbcTokenStore
     */
    @Bean
    public TokenStore jdbcTokenStore() {
        return new JdbcTokenStore(dataSource);
    }

    /**
     * 指定当前资源的ID和存储方案
     * @param resources
     * @throws Exception
     */
    @Override
    public void configure(ResourceServerSecurityConfigurer resources) throws Exception {
        //可以通过配置文件读取的方式加载resourceId，此处为方便，直接写死了
        resources.resourceId("product_api").tokenStore(jdbcTokenStore());
    }

    @Override
    public void configure(HttpSecurity http) throws Exception {
        /**
         * 固定配置，无需记住，了解即可。
         */
        http.authorizeRequests()
                //配置不同访问请求需要的权限
                .antMatchers(HttpMethod.GET, "/**").access("#oauth2.hasAnyScope('read')")
                .antMatchers(HttpMethod.POST, "/**").access("#oauth2.hasAnyScope('write')")
                .antMatchers(HttpMethod.PATCH, "/**").access("#oauth2.hasAnyScope('write')")
                .antMatchers(HttpMethod.PUT, "/**").access("#oauth2.hasAnyScope('write')")
                .antMatchers(HttpMethod.DELETE, "/**").access("#oauth2.hasAnyScope('write')")
                .and()
                .headers().addHeaderWriter((request, response) -> {//处理跨域请求
                    response.addHeader("Access-Control-Allow-Origin", "*");//允许跨域
                    if (request.getMethod().equals("OPTIONS")){//如果是跨域的预检请求，则原封不动向下传递请求投信息
                        response.setHeader("Access-Control-Allow-Methods",request.getHeader("Access-Control-Allow-Method"));
                        response.setHeader("Access-Control-Allow-Headers",request.getHeader("Access-Control-Allow-Headers"));
                    }
        });
    }
}
